package cn.edu.seu.cose.qol.ws.resource.admin;

import java.io.IOException;
import java.util.Collection;

import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;

import org.restlet.ext.xml.DomRepresentation;
import org.restlet.representation.Representation;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.xml.sax.SAXException;

import cn.edu.seu.cose.qol.model.dao.database.account.AdminAccountDataAccess;
import cn.edu.seu.cose.qol.model.dto.admin.AdminInstance;
import cn.edu.seu.cose.qol.model.dto.admin.Admins;
import cn.edu.seu.cose.qol.model.po.account.AdminAccount;
import cn.edu.seu.cose.qol.ws.resource.QolServerResource;
import cn.edu.seu.cose.qol.ws.resource.util.DomRepresentationBuilder;
import cn.edu.seu.cose.qol.ws.resource.util.XmlObjectReader;
import cn.edu.seu.cose.qol.ws.resource.util.adapter.AdminAdapter;
import cn.edu.seu.cose.qol.ws.resource.util.adapter.AdminsAdapter;

public class AdminsResource extends QolServerResource {
	
	private static final String OFFSET_PARAM_NAME = "offset";
	
	private static final String ROW_PARAM_NAME = "row";
	
	private static Representation getRepresentationByAdminAccounts(
			Collection<AdminAccount> adminAccounts)
					throws JAXBException, IOException, SAXException,
					ParserConfigurationException {
		AdminsAdapter adapter = AdminsAdapter.getInstance();
		Admins admins = adapter.adapt(adminAccounts);
		
		DomRepresentationBuilder builder =
				DomRepresentationBuilder.getInstance();
		return builder.getRepresentation(admins);
	}
	
	@Get("xml")
	public Representation getAllAdministrators() {
		try {
			String offsetParam = getQuery().getFirstValue(OFFSET_PARAM_NAME);
			String rowParam = getQuery().getFirstValue(ROW_PARAM_NAME);
			
			AdminAccountDataAccess dao = AdminAccountDataAccess.getInstance();
			
			// uri = /admins
			if (offsetParam == null && rowParam == null) {
				Collection<AdminAccount> adminAccounts = dao.getAdminAccounts();
				return getRepresentationByAdminAccounts(adminAccounts);
			}
			
			// uri = /admins?row={n}
			if (offsetParam == null && rowParam != null) {
				long offset = 0;
				long row = Long.valueOf(rowParam);
				Collection<AdminAccount> adminAccounts =
						dao.getAdminAccounts(offset, row);
				return getRepresentationByAdminAccounts(adminAccounts);
			}
			
			// uri = /admins?offset={n1}&row={n2}
			if (offsetParam != null && rowParam != null) {
				long offset = Long.valueOf(offsetParam);
				long row = Long.valueOf(rowParam);
				Collection<AdminAccount> adminAccounts =
						dao.getAdminAccounts(offset, row);
				return getRepresentationByAdminAccounts(adminAccounts);
			}
			
			// else
			return getRepresentationByException(new IllegalParameterException());
		} catch (Exception e) {
			return getRepresentationByException(e);
		}
	}
	
	@Post("xml:xml")
	public Representation createNewAdministrator(
			Representation representation) {
		try {
			DomRepresentation inputRepresentation = new DomRepresentation(
					representation);
			XmlObjectReader reader = XmlObjectReader.getInstance();
			AdminInstance adminInstance = (AdminInstance) reader.getXmlObject(
					inputRepresentation, AdminInstance.class);
			AdminAdapter adapter = AdminAdapter.getInstance();
			AdminAccount adminAccount = adapter.adapt(adminInstance);
			
			AdminAccountDataAccess adminAccountAccess =
					AdminAccountDataAccess.getInstance();
			adminAccountAccess.createNewAdminAccount(adminAccount);
			return getSuccessRepresentation();
		} catch (Exception e) {
			return getRepresentationByException(e);
		}
	}
	
	private static class IllegalParameterException extends Exception {

		private static final long serialVersionUID = -2750637523142098663L;

		public IllegalParameterException() {
			super("param: row is needed");
		}

	}
	
}
